from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.decorators import action
from django.db.models import Q
import datetime
import pandas as pd
from io import BytesIO
from django.http import HttpResponse
import os
import uuid
from django.conf import settings
from ..tasks import import_orders_task

from ..models import Order, Customer, Product
from apps.UMM.models import User
from ..serializers import OrderListSerializer, OrderCreateUpdateSerializer

class OrderViewSet(viewsets.ModelViewSet):
    """订单视图集"""
    queryset = Order.objects.all().order_by('-order_date', '-creation_date')
    
    def get_serializer_class(self):
        if self.action in ['create', 'update', 'partial_update']:
            return OrderCreateUpdateSerializer
        return OrderListSerializer
    
    def get_queryset(self):
        """实现多条件过滤查询"""
        queryset = super().get_queryset()
        
        # 获取查询参数
        customer_name = self.request.query_params.get('customer_name', None)
        order_number = self.request.query_params.get('order_number', None)
        authorized_domain = self.request.query_params.get('authorized_domain', None)
        nickname = self.request.query_params.get('nickname', None)
        order_status = self.request.query_params.get('order_status', None)
        order_date_start = self.request.query_params.get('order_date_start', None)
        order_date_end = self.request.query_params.get('order_date_end', None)
        activation_date_start = self.request.query_params.get('activation_date_start', None)
        activation_date_end = self.request.query_params.get('activation_date_end', None)
        product_name = self.request.query_params.get('product_name', None)
        is_invoice = self.request.query_params.get('is_invoice', None)
        is_double_coms = self.request.query_params.get('is_double_coms', None)
        
        # 应用过滤条件
        if customer_name:
            queryset = queryset.filter(customer_name__customer_name__icontains=customer_name)
        if order_number:
            queryset = queryset.filter(order_number__icontains=order_number)
        if authorized_domain:
            queryset = queryset.filter(authorized_domain__icontains=authorized_domain)
        if nickname:
            queryset = queryset.filter(nickname__nickname__icontains=nickname)
        if order_status is not None:
            queryset = queryset.filter(order_status=order_status)
        if order_date_start and order_date_end:
            queryset = queryset.filter(order_date__range=[order_date_start, order_date_end])
        elif order_date_start:
            queryset = queryset.filter(order_date__gte=order_date_start)
        elif order_date_end:
            queryset = queryset.filter(order_date__lte=order_date_end)
        if activation_date_start and activation_date_end:
            queryset = queryset.filter(activation_date__range=[activation_date_start, activation_date_end])
        elif activation_date_start:
            queryset = queryset.filter(activation_date__gte=activation_date_start)
        elif activation_date_end:
            queryset = queryset.filter(activation_date__lte=activation_date_end)
        if product_name:
            queryset = queryset.filter(product_name=product_name)
        if is_invoice is not None:
            queryset = queryset.filter(is_invoice=is_invoice)
        if is_double_coms is not None:
            queryset = queryset.filter(is_double_coms=is_double_coms)
            
        return queryset
    
    @action(detail=False, methods=['post'])
    def batch_delete(self, request):
        """批量删除订单"""
        ids = request.data.get('ids', [])
        if not ids:
            return Response({"message": "未提供要删除的订单ID"}, status=status.HTTP_400_BAD_REQUEST)
        
        Order.objects.filter(id__in=ids).delete()
        return Response({"message": "批量删除成功"}, status=status.HTTP_200_OK)
    
    @action(detail=False, methods=['post'])
    def batch_mark_invoice(self, request):
        """批量标记开票状态"""
        ids = request.data.get('ids', [])
        if not ids:
            return Response({"message": "未提供要标记的订单ID"}, status=status.HTTP_400_BAD_REQUEST)
        
        Order.objects.filter(id__in=ids).update(is_invoice=1)
        return Response({"message": "批量标记开票成功"}, status=status.HTTP_200_OK)
    
    @action(detail=False, methods=['get'])
    def export(self, request):
        """导出订单数据为Excel"""
        queryset = self.get_queryset()
        
        # 创建一个空的DataFrame
        df = pd.DataFrame()
        
        # 添加所需列
        df['订单ID'] = [order.id for order in queryset]
        df['订单来源'] = [order.get_order_source_display() for order in queryset]
        df['订单号'] = [order.order_number for order in queryset]
        df['客户名称'] = [order.customer_name.customer_name for order in queryset]
        df['下单日期'] = [order.order_date for order in queryset]
        df['产品名称'] = [order.product_name.product_name for order in queryset]
        df['订单金额'] = [order.order_amount for order in queryset]
        df['购买年限'] = [order.get_purchase_years_display() for order in queryset]
        df['订单状态'] = [order.get_order_status_display() for order in queryset]
        df['授权域名'] = [order.authorized_domain for order in queryset]
        df['激活日期'] = [order.activation_date for order in queryset]
        df['昵称'] = [order.nickname.nickname if order.nickname else '' for order in queryset]
        df['授权码'] = [order.authorization_code for order in queryset]
        df['订单备注'] = [order.order_remarks for order in queryset]
        df['是否已开票'] = [order.get_is_invoice_display() for order in queryset]
        df['创建日期'] = [order.creation_date.replace(tzinfo=None) if order.creation_date else None for order in queryset]
        df['最后修改日期'] = [order.last_modification_date.replace(tzinfo=None) if order.last_modification_date else None for order in queryset]
        df['激活提成'] = [order.commission for order in queryset]
        df['是否双倍提成'] = [order.get_is_double_coms_display() for order in queryset]
        
        # 创建一个字节流
        output = BytesIO()
        
        try:
            # 将DataFrame写入Excel
            with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
                df.to_excel(writer, sheet_name='订单数据', index=False)
                
            # 设置文件指针到开始
            output.seek(0)
            
            # 创建响应
            response = HttpResponse(output.read(), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
            response['Content-Disposition'] = 'attachment; filename=订单数据.xlsx'
            
            return response
        except Exception as e:
            # 记录错误并返回错误响应
            import logging
            logger = logging.getLogger(__name__)
            logger.error(f"导出订单数据失败: {str(e)}")
            return Response({"message": f"导出失败: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        
    @action(detail=False, methods=['get'])
    def import_template(self, request):
        """获取订单导入模板"""
        # 创建一个包含示例数据的DataFrame
        sample_data = [
            {
                '订单号': 'ORD2023001',
                '客户名称': '示例客户名称',
                '下单日期': '2023-01-01',
                '产品名称': 'Elementor Pro',
                '订单金额': 18.80,
                '购买年限': '1年',
                '订单状态': '未激活',
                '授权域名': 'example.com',
                '激活日期': '',
                '激活人': '',
                '授权码': '123456abcdef',
                '订单备注': '这是一个未激活的示例订单',
                '是否已开票': '否',
                '是否双倍提成': '否',
                '订单来源': 'Newbe工作室'
            },
            {
                '订单号': 'ORD2023002',
                '客户名称': '示例客户名称',
                '下单日期': '2023-01-02',
                '产品名称': 'Elementor Pro',
                '订单金额': 28.80,
                '购买年限': '2年',
                '订单状态': '已激活',
                '授权域名': 'client-domain.com',
                '激活日期': '2023-01-05',
                '激活人': '测试',
                '授权码': 'abcdef123456',
                '订单备注': '这是一个已激活的示例订单',
                '是否已开票': '是',
                '是否双倍提成': '否',
                '订单来源': '纽币德信息科技'
            },
            {
                '订单号': 'ORD2023003',
                '客户名称': '示例客户名称',
                '下单日期': '2023-01-03',
                '产品名称': 'Elementor Pro',
                '订单金额': 38.80,
                '购买年限': '3年',
                '订单状态': '临时IP激活',
                '授权域名': '',
                '激活日期': '2023-01-06',
                '激活人': '测试',
                '授权码': 'temp987654',
                '订单备注': '这是一个临时IP激活的示例订单，无需填写授权域名',
                '是否已开票': '否',
                '是否双倍提成': '是',
                '订单来源': '官方网站'
            }
        ]
        
        df = pd.DataFrame(sample_data)
        
        # 创建一个字节流
        output = BytesIO()
        
        # 将DataFrame写入Excel
        with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
            df.to_excel(writer, sheet_name='订单导入模板', index=False)
            workbook = writer.book
            worksheet = writer.sheets['订单导入模板']
            
            # 设置列宽
            for i, col in enumerate(df.columns):
                column_width = max(len(col)*1.5, 15)
                worksheet.set_column(i, i, column_width)
            
            # 添加示例和说明
            # 设置说明格式
            format_header = workbook.add_format({
                'bold': True,
                'font_color': 'white',
                'bg_color': '#1890ff',
                'border': 1,
                'align': 'center',
                'valign': 'vcenter',
                'font_size': 11
            })
            
            format_info = workbook.add_format({
                'bold': True,
                'font_color': 'red',
                'font_size': 12
            })
            
            # 添加字段说明到单元格注释
            notes = {
                '订单号': '必填。订单号必须唯一，可以使用任何字符',
                '客户名称': '必填。客户名称必须已经存在于系统中',
                '下单日期': '必填。格式: YYYY-MM-DD, 例如: 2023-01-01',
                '产品名称': '必填。产品名称必须已经存在于系统中',
                '订单金额': '必填。数字格式, 例如: 18.80',
                '购买年限': '必填。可选值: 永久, 1年, 2年, 3年, 4年, 5年',
                '订单状态': '必填。可选值: 未激活, 已激活, 临时IP激活',
                '授权域名': '选填。客户的域名，例如: example.com (可以为空)',
                '激活日期': '选填。格式: YYYY-MM-DD (可以为空)',
                '激活人': '选填。系统中存在的用户昵称 (可以为空)',
                '授权码': '选填。授权码 (可以为空)',
                '订单备注': '选填。订单备注 (可以为空)',
                '是否已开票': '选填。可选值: 是, 否（默认为否）',
                '是否双倍提成': '选填。可选值: 是, 否（默认为否）',
                '订单来源': '必填。可选值: Newbe工作室, 纽币德信息科技, 官方网站, 其它'
            }
            
            for col_num, (column, note) in enumerate(notes.items()):
                worksheet.write_comment(0, col_num, note)
                
                # 为表头设置格式
                worksheet.write(0, col_num, column, format_header)
            
            # 添加使用说明
            info_sheet = workbook.add_worksheet('使用说明')
            info_sheet.set_column(0, 0, 15)
            info_sheet.set_column(1, 1, 80)
            
            # 添加使用说明内容
            instructions = [
                ['步骤', '说明'],
                ['1', '下载此模板并打开'],
                ['2', '按照"订单导入模板"工作表中的格式填写您的订单数据'],
                ['3', '确保所有必填字段都已填写，并且符合指定的格式要求'],
                ['4', '保存文件为.xlsx格式'],
                ['5', '上传填写好的文件到系统进行导入'],
                ['', ''],
                ['注意事项', '说明'],
                ['客户必须存在', '导入前请确保客户名称已经在系统中存在，否则导入会失败'],
                ['产品必须存在', '导入前请确保产品名称已经在系统中存在，否则导入会失败'],
                ['激活人必须存在', '如果填写了激活人，该用户昵称必须已经在系统中存在，否则导入会失败'],
                ['日期格式', '所有日期必须使用YYYY-MM-DD格式，例如2023-01-01'],
                ['枚举值', '对于有固定选项的字段（如订单来源、购买年限等），必须使用规定的值']
            ]
            
            # 设置表头格式
            header_format = workbook.add_format({
                'bold': True,
                'bg_color': '#1890ff',
                'font_color': 'white',
                'border': 1,
                'align': 'center',
                'valign': 'vcenter',
                'font_size': 12
            })
            
            # 设置内容格式
            content_format = workbook.add_format({
                'border': 1,
                'align': 'left',
                'valign': 'vcenter',
                'text_wrap': True
            })
            
            # 设置标题行格式
            title_format = workbook.add_format({
                'bold': True,
                'font_color': '#1890ff',
                'border': 1,
                'align': 'center',
                'valign': 'vcenter',
                'font_size': 11
            })
            
            # 写入说明内容
            for row_num, instruction in enumerate(instructions):
                if row_num == 0:
                    info_sheet.write(row_num, 0, instruction[0], header_format)
                    info_sheet.write(row_num, 1, instruction[1], header_format)
                elif instruction[0] in ['注意事项']:
                    info_sheet.write(row_num, 0, instruction[0], title_format)
                    info_sheet.write(row_num, 1, instruction[1], title_format)
                else:
                    info_sheet.write(row_num, 0, instruction[0], content_format)
                    info_sheet.write(row_num, 1, instruction[1], content_format)
                
        # 设置文件指针到开始
        output.seek(0)
        
        # 创建响应
        response = HttpResponse(output.read(), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        response['Content-Disposition'] = 'attachment; filename=订单导入模板.xlsx'
        
        return response
        
    @action(detail=False, methods=['post'], url_path='import')
    def import_data(self, request):
        """导入订单数据"""
        import logging
        logger = logging.getLogger(__name__)
        logger.info("开始处理订单导入请求")
        
        if 'file' not in request.FILES:
            logger.error("没有接收到文件")
            return Response({"success": False, "message": "请上传文件"}, status=status.HTTP_400_BAD_REQUEST)
        
        file = request.FILES['file']
        logger.info(f"接收到文件: {file.name}, 大小: {file.size} 字节")
        
        # 检查文件类型
        if not file.name.endswith(('.xlsx', '.xls')):
            logger.error(f"不支持的文件类型: {file.name}")
            return Response({"success": False, "message": "只支持Excel文件(.xlsx或.xls)"}, status=status.HTTP_400_BAD_REQUEST)
        
        try:
            # 创建临时目录（如果不存在）
            temp_dir = os.path.join(settings.BASE_DIR, 'temp_uploads')
            os.makedirs(temp_dir, exist_ok=True)
            
            # 保存上传的文件到临时位置
            file_extension = os.path.splitext(file.name)[1]
            temp_filename = f"order_import_{uuid.uuid4().hex}{file_extension}"
            temp_file_path = os.path.join(temp_dir, temp_filename)
            
            with open(temp_file_path, 'wb+') as destination:
                for chunk in file.chunks():
                    destination.write(chunk)
                    
            logger.info(f"已保存上传文件到临时位置: {temp_file_path}")
            
            # 尝试异步处理文件导入
            try:
                # 启动异步任务
                task = import_orders_task.delay(temp_file_path)
                
                # 返回任务ID
                return Response({
                    'success': True,
                    'message': '已开始处理导入任务，请稍后刷新页面查看结果',
                    'task_id': task.id
                })
            except Exception as task_error:
                # 如果异步任务启动失败，记录错误并回退到同步处理
                logger.warning(f"异步任务启动失败，将使用同步方式处理: {str(task_error)}")
                
                # 直接调用任务函数进行同步处理
                result = import_orders_task(temp_file_path)
                return Response(result)
            
        except Exception as e:
            logger.exception("导入准备过程中发生错误")
            return Response({"success": False, "message": f"导入失败: {str(e)}"}, status=status.HTTP_400_BAD_REQUEST)
    
    @action(detail=False, methods=['get'])
    def commission(self, request):
        """
        获取激活提成明细数据
        提供已激活订单的提成明细，包括激活人、订单金额和提成金额等信息
        """
        queryset = self.get_queryset()
        
        # 只获取已激活的订单
        queryset = queryset.filter(order_status=1)
        
        # 获取查询参数
        date_start = self.request.query_params.get('date_start', None)
        date_end = self.request.query_params.get('date_end', None)
        nickname = self.request.query_params.get('nickname', None)
        product_name = self.request.query_params.get('product_name', None)
        
        # 应用过滤条件
        if date_start and date_end:
            queryset = queryset.filter(activation_date__range=[date_start, date_end])
        elif date_start:
            queryset = queryset.filter(activation_date__gte=date_start)
        elif date_end:
            queryset = queryset.filter(activation_date__lte=date_end)
        
        if nickname:
            # 使用nickname__nickname而不是nickname__nickname+role过滤，确保包含所有角色
            queryset = queryset.filter(nickname__nickname=nickname)
        
        if product_name:
            queryset = queryset.filter(product_name__product_name=product_name)
        
        # 分页
        page = int(request.query_params.get('page', 1))
        limit = int(request.query_params.get('limit', 10))
        start = (page - 1) * limit
        end = page * limit
        
        # 准备返回结果
        result = []
        for order in queryset[start:end]:
            # 计算提成比例
            commission_ratio = 0
            if order.product_name and order.product_name.commission_category:
                commission_ratio = order.product_name.commission_category.commission_ratio
            
            result.append({
                'id': order.id,
                'order_number': order.order_number,
                'nickname': order.nickname.nickname if order.nickname else '',
                'customer_name': order.customer_name.customer_name,
                'product_name': order.product_name.product_name,
                'order_date': order.order_date,
                'activation_date': order.activation_date,
                'order_amount': float(order.order_amount),
                'commission': float(order.commission) if order.commission else 0,
                'commission_ratio': float(commission_ratio),
                'is_double_coms': order.is_double_coms,
                'role': order.nickname.role if order.nickname else None  # 添加角色信息，便于前端判断
            })
        
        return Response({
            'code': 200,
            'message': '获取提成明细成功',
            'data': {
                'total': queryset.count(),
                'items': result
            }
        })
    
    @action(detail=False, methods=['get'], url_path='commission/export')
    def export_commission(self, request):
        """导出提成明细数据"""
        # 获取查询参数
        order_date_start = self.request.query_params.get('order_date_start', None)
        order_date_end = self.request.query_params.get('order_date_end', None)
        activation_date_start = self.request.query_params.get('activation_date_start', None)
        activation_date_end = self.request.query_params.get('activation_date_end', None)
        nickname = self.request.query_params.get('nickname', None)
        product_name = self.request.query_params.get('product_name', None)
        authorized_domain = self.request.query_params.get('authorized_domain', None)
        commission_min = self.request.query_params.get('commission_min', None)
        commission_max = self.request.query_params.get('commission_max', None)
        
        # 基础查询：已激活的订单
        queryset = Order.objects.filter(order_status=1)
        
        # 添加额外的过滤条件
        if order_date_start and order_date_end:
            queryset = queryset.filter(order_date__range=[order_date_start, order_date_end])
        elif order_date_start:
            queryset = queryset.filter(order_date__gte=order_date_start)
        elif order_date_end:
            queryset = queryset.filter(order_date__lte=order_date_end)
            
        if activation_date_start and activation_date_end:
            queryset = queryset.filter(activation_date__range=[activation_date_start, activation_date_end])
        elif activation_date_start:
            queryset = queryset.filter(activation_date__gte=activation_date_start)
        elif activation_date_end:
            queryset = queryset.filter(activation_date__lte=activation_date_end)
        
        if nickname:
            queryset = queryset.filter(nickname__nickname__icontains=nickname)
        
        if product_name:
            queryset = queryset.filter(product_name=product_name)
            
        if authorized_domain:
            queryset = queryset.filter(authorized_domain__icontains=authorized_domain)
            
        if commission_min:
            queryset = queryset.filter(commission__gte=commission_min)
            
        if commission_max:
            queryset = queryset.filter(commission__lte=commission_max)
        
        # 创建输出DF
        df = pd.DataFrame()
        
        # 添加列数据
        df['订单号'] = [order.order_number for order in queryset]
        df['客户名称'] = [order.customer_name.customer_name for order in queryset]
        df['产品名称'] = [order.product_name.product_name for order in queryset]
        df['提成分类'] = [order.product_name.commission_category.commission_category for order in queryset]
        df['提成比例'] = [order.product_name.commission_category.commission_ratio for order in queryset]
        df['订单金额'] = [order.order_amount for order in queryset]
        df['激活提成'] = [order.commission for order in queryset]
        df['是否双倍提成'] = [order.get_is_double_coms_display() for order in queryset]
        df['订单日期'] = [order.order_date for order in queryset]
        df['激活日期'] = [order.activation_date for order in queryset]
        df['激活人'] = [order.nickname.nickname if order.nickname else '' for order in queryset]
        df['授权域名'] = [order.authorized_domain for order in queryset]
        
        # 创建字节流
        output = BytesIO()
        
        # 写入Excel
        with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
            df.to_excel(writer, sheet_name='提成明细数据', index=False)
            
            # 设置列宽
            worksheet = writer.sheets['提成明细数据']
            for i, col in enumerate(df.columns):
                column_width = max(len(col) * 1.5, 15)
                worksheet.set_column(i, i, column_width)
        
        output.seek(0)
        
        # 创建响应
        response = HttpResponse(output.read(), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        response['Content-Disposition'] = 'attachment; filename=提成明细数据.xlsx'
        
        return response
    
    @action(detail=False, methods=['get'])
    def server_rental(self, request):
        """获取主机出租订单列表"""
        try:
            # 获取查询参数
            queryset = self.get_queryset()
            
            # 简化筛选逻辑，直接获取产品名称包含"主机出租"的产品ID
            server_rental_products = Product.objects.filter(
                product_name__icontains='主机出租'
            )
            
            # 获取这些产品的ID
            product_ids = server_rental_products.values_list('id', flat=True)
            
            # 筛选订单
            queryset = queryset.filter(product_name__id__in=product_ids)
            
            # 实现分页
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
            
            serializer = self.get_serializer(queryset, many=True)
            return Response(serializer.data)
        except Exception as e:
            import logging
            logger = logging.getLogger(__name__)
            logger.error(f"获取主机出租订单失败: {str(e)}")
            return Response({"message": f"获取主机出租订单失败: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    @action(detail=False, methods=['get'], url_path='server-rental/export')
    def export_server_rental(self, request):
        """导出主机出租订单数据"""
        try:
            # 使用与server_rental接口相同的过滤逻辑
            queryset = self.get_queryset()
            
            # 简化筛选逻辑，直接获取产品名称包含"主机出租"的产品ID
            server_rental_products = Product.objects.filter(
                product_name__icontains='主机出租'
            )
            
            product_ids = server_rental_products.values_list('id', flat=True)
            queryset = queryset.filter(product_name__id__in=product_ids)
            
            # 创建DataFrame
            df = pd.DataFrame()
            
            # 添加列
            df['订单号'] = [order.order_number for order in queryset]
            df['客户名称'] = [order.customer_name.customer_name for order in queryset]
            df['产品名称'] = [order.product_name.product_name for order in queryset]
            df['订单金额'] = [order.order_amount for order in queryset]
            df['下单日期'] = [order.order_date for order in queryset]
            df['网站域名'] = [order.authorized_domain for order in queryset]
            df['生效日期'] = [order.activation_date for order in queryset]
            df['截至日期'] = [
                (order.activation_date + datetime.timedelta(days=365*order.purchase_years)) 
                if order.activation_date and order.purchase_years > 0 
                else '永久' 
                for order in queryset
            ]
            df['对接人'] = [order.nickname.nickname if order.nickname else '' for order in queryset]
            df['订单备注'] = [order.order_remarks for order in queryset]
            df['购买年限'] = [order.get_purchase_years_display() for order in queryset]
            df['授权码'] = [order.authorization_code for order in queryset]
            
            # 创建字节流
            output = BytesIO()
            
            # 写入Excel
            with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
                df.to_excel(writer, sheet_name='主机出租数据', index=False)
                
                # 设置列宽
                worksheet = writer.sheets['主机出租数据']
                for i, col in enumerate(df.columns):
                    column_width = max(len(col) * 1.5, 15)
                    worksheet.set_column(i, i, column_width)
            
            output.seek(0)
            
            # 创建响应
            response = HttpResponse(output.read(), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
            response['Content-Disposition'] = 'attachment; filename=主机出租数据.xlsx'
            
            return response
        except Exception as e:
            import logging
            logger = logging.getLogger(__name__)
            logger.error(f"导出主机出租数据失败: {str(e)}")
            return Response({"message": f"导出主机出租数据失败: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) 